"""
OracleDataService 时间段查询测试文件
用于测试 OracleDataService 类中支持时间段查询的方法
详细打印所有数据
"""

import sys
import os
import logging
from datetime import datetime, timedelta
import json

# 添加项目根目录到Python路径
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, project_root)

from tools.juyuan_tools.service.oracle_data_service import OracleDataService


def print_all_data(data, data_name, max_display=1000):
    """打印所有数据，控制显示数量"""
    print(f"\n{'=' * 80}")
    print(f"{data_name} - 共 {len(data)} 条记录:")
    print(f"{'=' * 80}")

    if not data:
        print("无数据")
        return

    # 打印所有数据，但限制最大显示数量
    display_count = min(len(data), max_display)
    for i, record in enumerate(data[:display_count], 1):
        print(f"\n记录 {i}/{len(data)}:")
        for key, value in record.items():
            # 如果是日期或数字，直接显示
            if isinstance(value, (datetime, int, float)):
                print(f"  {key}: {value}")
            # 如果是字典或列表，格式化为JSON
            elif isinstance(value, (dict, list)):
                try:
                    formatted = json.dumps(value, ensure_ascii=False, indent=2)
                    if len(formatted) > 200:  # 如果太长，只显示部分
                        formatted = json.dumps(value, ensure_ascii=False)[:200] + "..."
                    print(f"  {key}: {formatted}")
                except:
                    print(f"  {key}: {value}")
            else:
                print(f"  {key}: {value}")

    if len(data) > display_count:
        print(f"\n... 还有 {len(data) - display_count} 条记录未显示 ...")


def test_date_range_queries():
    """测试时间段查询功能"""
    print("开始测试时间段查询功能...")

    # 设置日志级别
    logging.basicConfig(level=logging.INFO)

    # 创建服务实例
    service = OracleDataService()

    # 检查数据库连接
    if service.db_session is None:
        print("数据库连接失败，无法进行测试")
        return

    print("数据库连接成功，开始测试...")

    # 测试数据
    fund_name = "诺安成长混合A"
    manager_name = "刘慧影"

    # 获取当前日期
    end_date = datetime.now().strftime("%Y-%m-%d")
    # 计算三个月前的日期
    start_date = (datetime.now() - timedelta(days=100)).strftime("%Y-%m-%d")

    print(f"测试数据: 基金名称={fund_name}, 时间段={start_date} 到 {end_date}, 基金经理={manager_name}")
    print("=" * 80)

    # 1. 测试匹配基金
    print("1. 测试匹配基金...")
    try:
        match_result = service.match_fund(fund_name=fund_name)
        print(f"匹配到 {len(match_result)} 个基金:")
        print_all_data(match_result, "匹配基金结果")
        if match_result:
            fund_code = match_result[0].get('基金代码', '')
            innercode = match_result[0].get('内部代码', '')
            print(f"\n使用第一个匹配结果: 基金代码: {fund_code}, 内部代码: {innercode}")
        else:
            fund_code = ''
            innercode = ''
            print("未匹配到基金")
    except Exception as e:
        print(f"匹配基金时发生错误: {e}")
        fund_code = ''
        innercode = ''

    print("\n" + "-" * 80)

    # 2. 测试获取基金净值信息（时间段查询）
    print("2. 测试获取基金净值信息（时间段查询）...")
    try:
        if fund_code:
            net_value = service.get_net_value(
                fund_code=fund_code,
                start_date=start_date,
                end_date=end_date
            )
            print_all_data(net_value, "基金净值信息（时间段）")
        else:
            print("由于未获取到基金代码，跳过此测试")
    except Exception as e:
        print(f"获取基金净值信息（时间段）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 3. 测试获取基金业绩表现（时间段查询）
    print("3. 测试获取基金业绩表现（时间段查询）...")
    try:
        performance = service.get_fund_performance(
            fund_code=fund_code,
            start_date=start_date,
            end_date=end_date
        )
        print_all_data(performance, "基金业绩表现（时间段）")
    except Exception as e:
        print(f"获取基金业绩表现（时间段）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 4. 测试获取十大重仓股（时间段查询）
    print("4. 测试获取十大重仓股（时间段查询）...")
    try:
        top_stocks = service.get_top_ten_stocks(
            fund_code=fund_code,
            start_date=start_date,
            end_date=end_date
        )
        print_all_data(top_stocks, "十大重仓股（时间段）")
    except Exception as e:
        print(f"获取十大重仓股（时间段）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 5. 测试获取前五大债券持仓（时间段查询）
    print("5. 测试获取前五大债券持仓（时间段查询）...")
    try:
        top_bonds = service.get_top_five_bonds(
            fund_code=fund_code,
            start_date=start_date,
            end_date=end_date
        )
        print_all_data(top_bonds, "前五大债券持仓（时间段）")
    except Exception as e:
        print(f"获取前五大债券持仓（时间段）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 6. 测试获取全部股票持仓（时间段查询）
    print("6. 测试获取全部股票持仓（时间段查询）...")
    try:
        all_stocks = service.get_all_stocks(
            fund_code=fund_code,
            start_date=start_date,
            end_date=end_date
        )
        print_all_data(all_stocks, "全部股票持仓（时间段）")
    except Exception as e:
        print(f"获取全部股票持仓（时间段）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 7. 测试获取全部债券持仓（时间段查询）
    print("7. 测试获取全部债券持仓（时间段查询）...")
    try:
        all_bonds = service.get_all_bonds(
            fund_code=fund_code,
            start_date=start_date,
            end_date=end_date
        )
        print_all_data(all_bonds, "全部债券持仓（时间段）")
    except Exception as e:
        print(f"获取全部债券持仓（时间段）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 8. 测试获取股票持仓变动（时间段查询）
    print("8. 测试获取股票持仓变动（时间段查询）...")
    try:
        stocks_change = service.get_stocks_change(
            fund_code=fund_code,
            start_date=start_date,
            end_date=end_date
        )
        print_all_data(stocks_change, "股票持仓变动（时间段）")
    except Exception as e:
        print(f"获取股票持仓变动（时间段）时发生错误: {e}")

    print("\n" + "=" * 80)
    print("所有时间段查询测试完成")


def test_only_end_date_queries():
    """测试只传入end_date的查询功能"""
    print("开始测试只传入end_date的查询功能...")

    # 创建服务实例
    service = OracleDataService()

    # 检查数据库连接
    if service.db_session is None:
        print("数据库连接失败，无法进行测试")
        return

    # 测试数据
    fund_name = "诺安成长混合"
    end_date = "2025-09-30"  # 指定一个具体的结束日期

    print(f"测试数据: 基金名称={fund_name}, 结束日期={end_date} (不传开始日期)")
    print("=" * 80)

    # 0. 测试匹配基金
    print("0. 测试匹配基金...")
    try:
        match_result = service.match_fund(fund_name=fund_name)
        print(f"匹配到 {len(match_result)} 个基金:")
        print_all_data(match_result, "匹配基金结果")
        if match_result:
            fund_code = match_result[0].get('基金代码', '')
            innercode = match_result[0].get('内部代码', '')
            print(f"\n使用第一个匹配结果: 基金代码: {fund_code}, 内部代码: {innercode}")
        else:
            fund_code = ''
            innercode = ''
            print("未匹配到基金")
    except Exception as e:
        print(f"匹配基金时发生错误: {e}")
        fund_code = ''
        innercode = ''

    print("\n" + "-" * 80)

    # 测试获取基金业绩表现（只传end_date）
    print("1. 测试获取基金业绩表现（只传end_date）...")
    try:
        performance = service.get_fund_performance(
            fund_code=fund_code,
            start_date=None,
            end_date=end_date
        )
        print_all_data(performance, "基金业绩表现（只传end_date）")
    except Exception as e:
        print(f"获取基金业绩表现（只传end_date）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 测试获取十大重仓股（只传end_date）
    print("2. 测试获取十大重仓股（只传end_date）...")
    try:
        top_stocks = service.get_top_ten_stocks(
            fund_code=fund_code,
            start_date=None,
            end_date=end_date
        )
        print_all_data(top_stocks, "十大重仓股（只传end_date）")
    except Exception as e:
        print(f"获取十大重仓股（只传end_date）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 测试获取前五大债券持仓（只传end_date）
    print("3. 测试获取前五大债券持仓（只传end_date）...")
    try:
        top_bonds = service.get_top_five_bonds(
            fund_code=fund_code,
            start_date=None,
            end_date=end_date
        )
        print_all_data(top_bonds, "前五大债券持仓（只传end_date）")
    except Exception as e:
        print(f"获取前五大债券持仓（只传end_date）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 测试获取全部股票持仓（只传end_date）
    print("4. 测试获取全部股票持仓（只传end_date）...")
    try:
        all_stocks = service.get_all_stocks(
            fund_code=fund_code,
            start_date=None,
            end_date=end_date
        )
        print_all_data(all_stocks, "全部股票持仓（只传end_date）")
    except Exception as e:
        print(f"获取全部股票持仓（只传end_date）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 测试获取全部债券持仓（只传end_date）
    print("5. 测试获取全部债券持仓（只传end_date）...")
    try:
        all_bonds = service.get_all_bonds(
            fund_code=fund_code,
            start_date=None,
            end_date=end_date
        )
        print_all_data(all_bonds, "全部债券持仓（只传end_date）")
    except Exception as e:
        print(f"获取全部债券持仓（只传end_date）时发生错误: {e}")

    print("\n" + "-" * 80)

    # 测试获取股票持仓变动（只传end_date）
    print("6. 测试获取股票持仓变动（只传end_date）...")
    try:
        stocks_change = service.get_stocks_change(
            fund_code=fund_code,
            start_date=None,
            end_date=end_date
        )
        print_all_data(stocks_change, "股票持仓变动（只传end_date）")
    except Exception as e:
        print(f"获取股票持仓变动（只传end_date）时发生错误: {e}")

    print("\n" + "=" * 80)
    print("所有只传入end_date的查询测试完成")


if __name__ == '__main__':
    test_date_range_queries()
    print("\n\n")
    test_only_end_date_queries()